home *** CD-ROM | disk | FTP | other *** search
- ; IMGPRCS2.ASM
- ;
- ; An image processing program (First optimization pass).
- ;
- ; This program blurs an eight-bit grayscale image by averaging a pixel
- ; in the image with the eight pixels around it. The average is computed
- ; by (CurCell*8 + other 8 cells)/16, weighting the current cell by 50%.
- ;
- ; Because of the size of the image (almost 64K), the input and output
- ; matrices are in different segments.
- ;
- ; Version #1: Straight-forward translation from Pascal to Assembly.
- ; Version #2: Three major optimizations. (1) used movsd instruction rather
- ; than a loop to copy data from DataOut back to DataIn.
- ; (2) Used repeat..until forms for all loops. (3) unrolled
- ; the innermost two loops (which is responsible for most of
- ; the performance improvement).
- ;
- ;
- ; Performance comparisons (66 MHz 80486 DX/2 system).
- ;
- ; This code- 6 seconds.
- ; Original ASM code- 36 seconds.
- ; Borland Pascal v7.0- 45 seconds.
- ; Borland C++ v4.02- 29 seconds.
- ; Microsoft C++ v8.00- 21 seconds.
-
- .xlist
- include stdlib.a
- includelib stdlib.lib
- .list
- .386
- option segment:use16
-
- dseg segment para public 'data'
-
- ; Loop control variables and other variables:
-
- h word ?
- i word ?
- j word ?
- k word ?
- l word ?
- sum word ?
- iterations word ?
-
- ; File names:
-
- InName byte "roller1.raw",0
- OutName byte "roller2.raw",0
-
- dseg ends
-
-
- ; Here is the input data that we operate on.
-
- InSeg segment para public 'indata'
-
- DataIn byte 251 dup (256 dup (?))
-
- InSeg ends
-
-
- ; Here is the output array that holds the result.
-
- OutSeg segment para public 'outdata'
-
- DataOut byte 251 dup (256 dup (?))
-
- OutSeg ends
-
-
-
-
- cseg segment para public 'code'
- assume cs:cseg, ds:dseg
-
- Main proc
- mov ax, dseg
- mov ds, ax
- meminit
-
- mov ax, 3d00h ;Open input file for reading.
- lea dx, InName
- int 21h
- jnc GoodOpen
- print
- byte "Could not open input file.",cr,lf,0
- jmp Quit
-
- ; Optimization modification- read the data into DataOut rather than
- ; DataIn because we'll move it into DataIn at the beginning of the
- ; h loop.
-
- GoodOpen: mov bx, ax ;File handle.
- mov dx, OutSeg ;Where to put the data.
- mov ds, dx
- lea dx, DataOut
- mov cx, 256*251 ;Size of data file to read.
- mov ah, 3Fh
- int 21h
- cmp ax, 256*251 ;See if we read the data.
- je GoodRead
- print
- byte "Did not read the file properly",cr,lf,0
- jmp Quit
-
- GoodRead: mov ax, dseg
- mov ds, ax
- print
- byte "Enter number of iterations: ",0
- getsm
- atoi
- free
- mov iterations, ax
- cmp ax, 0
- jle Quit
-
- print
- byte "Computing Result",cr,lf,0
-
- ; for h := 1 to iterations-
-
- mov h, 1
- hloop:
-
- ; Copy the input data to the output buffer.
- ; Optimization step #1: Replace with movs instruction.
-
- push ds
- mov ax, OutSeg
- mov ds, ax
- mov ax, InSeg
- mov es, ax
- lea si, DataOut
- lea di, DataIn
- mov cx, (251*256)/4
- rep movsd
- pop ds
-
-
- ; Optimization Step #1: Convert loops to repeat..until form.
-
- ; for i := 1 to 249 -
-
- mov i, 1
- iloop:
-
- ; for j := 1 to 254 -
-
- mov j, 1
- jloop:
-
-
- ; Optimization. Unroll the innermost two loops:
-
- mov bh, byte ptr i ;i is always less than 256.
- mov bl, byte ptr j ;Computes i*256+j!
-
- push ds
- mov ax, InSeg ;Gain access to InSeg.
- mov ds, ax
-
- mov cx, 0 ;Compute sum here.
- mov ah, ch
- mov cl, ds:DataIn[bx-257] ;DataIn[i-1][j-1]
- mov al, ds:DataIn[bx-256] ;DataIn[i-1][j]
- add cx, ax
- mov al, ds:DataIn[bx-255] ;DataIn[i-1][j+1]
- add cx, ax
- mov al, ds:DataIn[bx-1] ;DataIn[i][j-1]
- add cx, ax
- mov al, ds:DataIn[bx+1] ;DataIn[i][j+1]
- add cx, ax
- mov al, ds:DataIn[bx+255] ;DataIn[i+1][j-1]
- add cx, ax
- mov al, ds:DataIn[bx+256] ;DataIn[i+1][j]
- add cx, ax
- mov al, ds:DataIn[bx+257] ;DataIn[i+1][j+1]
- add cx, ax
-
- mov al, ds:DataIn[bx] ;DataIn[i][j]
- shl ax, 3 ;DataIn[i][j]*8
- add cx, ax
- shr cx, 4 ;Divide by 16
- mov ax, OutSeg
- mov ds, ax
- mov ds:DataOut[bx], cl
- pop ds
-
- inc j
- cmp j, 254
- jbe jloop
-
- inc i
- cmp i, 249
- jbe iloop
-
- inc h
- mov ax, h
- cmp ax, Iterations
- jnbe Done
- jmp hloop
-
- Done: print
- byte "Writing result",cr,lf,0
-
-
- ; Okay, write the data to the output file:
-
- mov ah, 3ch ;Create output file.
- mov cx, 0 ;Normal file attributes.
- lea dx, OutName
- int 21h
- jnc GoodCreate
- print
- byte "Could not create output file.",cr,lf,0
- jmp Quit
-
- GoodCreate: mov bx, ax ;File handle.
- push bx
- mov dx, OutSeg ;Where the data can be found.
- mov ds, dx
- lea dx, DataOut
- mov cx, 256*251 ;Size of data file to write.
- mov ah, 40h ;Write operation.
- int 21h
- pop bx ;Retrieve handle for close.
- cmp ax, 256*251 ;See if we wrote the data.
- je GoodWrite
- print
- byte "Did not write the file properly",cr,lf,0
- jmp Quit
-
- GoodWrite: mov ah, 3eh ;Close operation.
- int 21h
-
-
- Quit: ExitPgm ;DOS macro to quit program.
- Main endp
-
- cseg ends
-
- sseg segment para stack 'stack'
- stk byte 1024 dup ("stack ")
- sseg ends
-
- zzzzzzseg segment para public 'zzzzzz'
- LastBytes byte 16 dup (?)
- zzzzzzseg ends
- end Main
-